# 字典

# key-value 中的 key 必须是一个可哈希的对象，可以使用 hash() 函数来判断数据是否可哈希。
# 简单理解在一次程序运行结束前，无论该数据什么时候执行 hash() 函数，都能得到一个唯一确定的值。
# 一般情况下，不可变对象数据，都可以得到一个哈希值。所以，理论上，python 中的不可变对象数据都可以做为 key 使用。但是，为了方便使用，大多数情况下，都会使用字符串类型数据做为 key 使用。
# 在一次程序运行过程中，hash函数得会得到同一个哈希值
def my_hash():
    # 可哈希数据
    print(hash("ab"))
    print(hash(123))
    print(hash((1, 2, 3)))
    # 不可哈希数据
    # print(hash([1, 2, 3]))
    # print(hash((1, 2, [3])))
# my_hash()

# 字典的创建 dict = {key : value}
d1 = {"name": "Alice", "age": 25, "gender": "female"}
# 构造方法定义字典
def dict_construction():
    d2 = dict(one=1, two=2, three=3)
    d3 = dict([('two', 2), ('one', 1), ('three', 3)])
    d4 = dict((('two', 2), ('one', 1), ('three', 3)))
    d5 = dict([('two', 2), ['one', 1], ('three', 3)])
    d6 = dict({'one': 1, 'two': 2, 'three': 3})
    d7 = dict({'one': 1, 'three': 3}, two=2)
    d8 = dict(zip(['one', 'two', 'three'], [1, 2, 3]))

# 字典数据访问
def dict_visit():
    stu = {"name": "Tom", "age": 23, "gender": "male"}
    print(stu["name"])
    print(stu["age"])
    k = "gender"
    print(stu[k])
# dict_visit()

# 字典元素添加与修改
def dict_addoramend():
    stu = {"name": "Tom", "age": 23, "gender": "male"}
    print(stu)
    # 添加新元素
    stu["address"] = "BeiJing"
    print(stu)
    # 修改数据
    stu["name"] = "Jack"
    stu["address"] = "ShangHai"
    print(stu)
# dict_addoramend()

# 字典元素的删除
def dict_del():
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    print(stu)
    # 删除元素
    del stu['age']
    print(stu)
    del stu['address']
    print(stu)
# dict_del()

# 字典操作
# 字典数据获取类操作
# keys() 用来获取字典中所有的 key, 保存到一个列表中，并以 dict_keys类型返回
def dict_keys():
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    ks = stu.keys()
    print(ks)
# dict_keys()

# values() 用来获取字典中所有的 value ，保存到一个列表中，并以 dict_values 类型返回
def dict_values():
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    ks = stu.values()
    print(ks)
# dict_values()

# items() 用来获取字典中所有的键值对，每一个元素键值对都以一个元组保存，将所有元素元组保存到一个列表中，并以 dict_items 类型返回
def dict_items():
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    ks = stu.items()
    print(ks)
# dict_items()

# get(key, default) 用来获取 key 对应的值，如果指定的 key 不存在，则返回默认值。
# 字典可以使用 字典对象[key] 的形式获取键值对，但是该方法如果指定的 key 不存在，程序会抛出一个错误。此时可以使用 get() 替代该取值方法
def dict_get():
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    # 报错
    # print(stu["name"])
    # print(stu["hobby"])
    print(stu.get("name"))
    print(stu.get("hobby"))
    print(stu.get("hobby", "无数据"))
# dict_get()

# setdefault(key,default) 给一个不存在的 key 添加一个默认值并将该键值对保存到字典中。
# 在一些场景下，字典的 key 存在，但是该 key 却没有对应的值，此时，就可以使用该方法，为当前的 key 添加一个默认值。比如服务端要保存客户端发起请求时携带的请求头中的信息。
def dict_setdefault():
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    stu.setdefault("hobby1")
    print(stu)
    stu.setdefault("hobby2", "无")
    print(stu)
# dict_setdefault()

# fromkeys(keys,val) 用于创建一个新字典，以序列 keys 中元素做字典的键，value 为字典所有键对应的初始值,默认为 None。
# 该方法是一个静态方法，需要使用字典类型名 dict 调用。 该方法如果给给定 keys 参数，则所有的key对应值都为默认值 None,如果给定 val 值，则所有 key 对应的值为 val。
def dict_fromkeys():
    ks = ("name", "age", "gender")
    s1 = dict.fromkeys(ks)
    print(s1)
    s2 = dict.fromkeys(ks, "无")
    print(s2)
# dict_fromkeys()

# update(dict | iterable) 使用参数中的数据更新当前字典。
#该方法的参数可以接收一个字典（大多数的使用方式），也可以接收一个可迭代对象，如果参数数据中的 key 在当前字典中存在，则使用新值更新字典中的键值对，如果参数数据中的 key 在当前字内中不存在，则将键值对添加到当前字典中。
def dict_update():
    # 更新目标数据是一个字典
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    newStu = {"name": "Jack", "hobby": "eat"}
    stu.update(newStu)
    print(stu)
    # 更新目标数据是一个可迭代对象
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    newStu = (("name", "Rose"), ["hobby", "play"])
    stu.update(newStu)
    print(stu)
# dict_update()

# 字典删除类操作
# popitem() 用来获取并删除字典中的最后一个键值对，返回一个元组，如果字典为空时，则抛出一个错误
def dict_popitem():
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    v = stu.popitem()
    print(v)
    print(stu)

    v = stu.popitem()
    print(v)
    print(stu)

    # 报错
    # print({}.popitem())
# dict_popitem()

# pop(key) 用于获取并删除字典中指定 key 对应的键值对。如果指定的 key 不存在，则抛出错误
def dict_pop():
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    v = stu.pop("name")
    print(v)
    print(stu)
dict_pop()

# clear() 清空字典中所有的键值对元素
def dict_clear():
    stu = {'name': 'Tom', 'age': 23, 'gender': 'male', 'address': 'BeiJing'}
    print(stu)
    stu.clear()
    print(stu)
dict_clear()